/*
 * Vector.cpp
 *
 *  Created on: 2014年2月27日
 *      Author: Administrator
 */
#include <cmath>
#include <iostream>
#include "Vector.h"
using std::sin;
using std::cos;
using std::atan2;
using std::cout;
using std::endl;
//命名空间
namespace VECTOR {

const double Rad_to_deg = 57.2957795130823;
//private methods
//calculates magnitude from x and y
void Vector::set_mag(){
	mag=sqrt(x*x +y*y);
}

void Vector::set_ang(){
	if(x == 0.0 && y == 0.0)
		ang = 0.0;
	else
		ang =atan2(y,x);
}
void Vector::set_x(){
	x = mag * cos(ang);
}
void Vector::set_y(){
	y =mag * sin(ang);
}


Vector::Vector() {
	// TODO Auto-generated constructor stub
	x=y=mag=ang=0.0;
	mode ='r';
}
// construct vector from rectangular coordinates if form is r
// (the default) or else from polar coordinates if form is p
Vector::Vector(double n1,double n2,char form)
{
	mode = form;
	if(form =='r')
	{
		x = n1;
		y = n2;
		set_mag();
		set_ang();
	}
	else if(form =='p')
	{
		mag = n1;
		ang = n2;
		set_x();
		set_y();
	}
	else
	{
		cout<< "Incorrect 3rd argument to Vector()--";
		cout<< "Vector set to 0\n";
		x = y = mag = ang = 0.0;
		mode = 'r';
	}
	cout <<"call construct"<<endl;
}
void Vector::set(double n1,double n2,char form)
{
#if 0
	Vector(n1,n2,form);
#else
	mode = form;
	if(form =='r')
	{
		x = n1;
		y = n2;
		set_mag();
		set_ang();
	}
	else if(form =='p')
	{
		mag = n1;
		ang = n2;
		set_x();
		set_y();
	}
	else
	{
		cout<< "Incorrect 3rd argument to Vector()--";
		cout<< "Vector set to 0\n";
		x = y = mag = ang = 0.0;
		mode = 'r';
	}
#endif
}
Vector::~Vector() {
	// TODO Auto-generated destructor stub
	cout <<"call des construct"<<endl;
}

void Vector::poloar_mode()
{
	mode = 'p';
}

void Vector::rect_mode()
{
	mode = 'r';
}
/** @brief 重载操作符
 *	## 技巧: ##
 *	### 当通过运算要返回一个新的类对象时，则应考虑是否可以使用 ###
 *	### 类的构造函数来完成这样的工作,因为这样做可以确保新的对象总是以正确的方向创建的 ###
 *	- 返回过程
 *		-# 调用了复制构造函数
 *		-# 调用了析构函数
 *		-# 这里不能返回对象的引用，因为局部对象在函数返回时被删除，即调用了析构函数
 *		-# 因此函数返回，引用指向的对象已不存在
 */
Vector Vector::operator +(const Vector &b)const
{
	return Vector(x+b.x,y+b.y);
}
//subtract Vector b from a
Vector Vector::operator -(const Vector &b)const
{
	return Vector(x-b.x,y-b.y);
}
//reverse sign of Vector
Vector Vector::operator -()const
{
	return Vector(-x,-y);
}

//multiple vector by n
Vector Vector::operator *(double n)const
{
	return Vector(n*x,n*y);
}
// friend methods
// multiply n by Vector a
Vector operator*(double n,const Vector &a)
{
	return a*n;
}

//display rectangular coordinates if mode is r
// else display polar coordinates if mode is p
std::ostream & operator<<(std::ostream &os,const Vector &v)
{
	if('r' == v.mode)
	{
		os<<"(x,y) = ("<<v.x<<","<<v.y<<")";
	}
	else if('p' == v.mode)
	{
		os<<"(m,a) = ("<< v.mag <<","<< v.ang* Rad_to_deg <<")";
	}
	else
		os << "Vector object mode is invalid";
	return os;
}

} /* namespace VECTOR */


